package com.gsit.expenditure.controller;

import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.bouncycastle.asn1.x9.OtherInfo;

import com.gsit.expenditure.client.domina.BillBean;
import com.gsit.expenditure.client.domina.FXMLBase;
import com.gsit.expenditure.client.domina.OtherBillBean;
import com.gsit.expenditure.client.domina.TravelbillBean;
import com.gsit.expenditure.domain.Customer;
import com.gsit.expenditure.domain.Invoice;
import com.gsit.expenditure.domain.OtherBill;
import com.gsit.expenditure.domain.TravelBill;
import com.gsit.expenditure.services.BillService;
import com.gsit.expenditure.utils.AppContextLoader;
import com.gsit.expenditure.utils.BillStatus;
import com.gsit.expenditure.utils.Page;
import com.gsit.expenditure.utils.Utils;
import com.gsit.expenditure.utils.ViewHandler;

import eu.schudt.javafx.controls.calendar.DatePicker;

import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.util.StringConverter;
import javafx.util.converter.DoubleStringConverter;

public class OtherbillController  extends BaseController implements Initializable{

	@FXML private ComboBox<Customer> customerName;
	@FXML private TextField refNo;
	
	@FXML private HBox dateHbox;
	@FXML private DatePicker date;
	
	@FXML private TextField description;
	@FXML private TextField amount;
	
	
	//ERROR LABELS
	@FXML private Label custNameErrorLabel;
	@FXML private Label refnoErrorLabel;
	//@FXML private Label descriptionErrorLabel;
	@FXML private Label amountErrorLabel;
	@FXML private Label dateErrorLabel;
	
	
	private BillService billService;
	private Validator validator; 
	private OtherBillBean otherBillBean;
	private OtherBill otherBill;
	
	@Override
	public void initialize(URL  url, ResourceBundle bundle) {
		
		billService=AppContextLoader.getBean(BillService.class);
		otherBillBean=new OtherBillBean(null);
		
		customerName.getItems().addAll(billService.findCustomerName());
		System.out.println("OtherBill Controller>>>>>>>>>>>>"+billService.findCustomerName());
		
		dateHbox.getChildren();
		date = new DatePicker(Locale.ENGLISH);
		date.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
		date.getCalendarView().todayButtonTextProperty().set("Today");
		date.getCalendarView().setShowWeeks(false);
		date.getStylesheets().add("css/datepicker/DatePicker.css");
		dateHbox.getChildren().add(date);
		
		
		 //CONVERTER FOR customername FIELD
		customerName.setConverter(new StringConverter<Customer>() {
		@Override
		public String toString(Customer customer) {
			return customer.getFirstName();
		}
		@Override
		public Customer fromString(String customerName) {
			List<Customer> customers=billService.findCustomerName();
			Customer customer=null;
			for (Customer customer2 : customers) {
				if (customer2.getFirstName().equals(customerName)) {
					System.out.println("Customer FirstName>>>>>>>>>>>>>>"+customerName);
					customer=customer2;
					break;
				}
			}
			return customer;
			}
			});
			bind();
		}
	
	private void init() {
		
		if (this.otherBillBean.getOtherBill() == null)
			return;
		this.otherBill = this.otherBillBean.getOtherBill();
		date.setSelectedDate(otherBill.getBillDate());
		customerName.setValue(otherBill.getCustomer());
		refNo.setText(otherBill.getReferenceNumber());
		description.setText(otherBill.getDescription());
		amount.setText(""+otherBill.getAmount());
		
	}

	
	public void bind(){
		
		Bindings.bindBidirectional(otherBillBean.getCustomerName(), new SimpleObjectProperty<>(customerName.getSelectionModel().getSelectedItem()));
		System.out.println("OtherbillController-bind>>>>>>>>>>>>>"+customerName.getSelectionModel().getSelectedItem());
		
		Bindings.bindBidirectional(otherBillBean.getRefNo(), refNo.textProperty());
		Bindings.bindBidirectional(otherBillBean.getDescription(), description.textProperty());
		StringConverter doublerConverter = new DoubleStringConverter();
		Bindings.bindBidirectional(amount.textProperty(),otherBillBean.getAmount(),doublerConverter);
	}
	
	@Override
	public void onSave(){
		
		Boolean isUpdate = Boolean.FALSE;
		otherBillBean.setCustomerName(new SimpleObjectProperty<>(customerName.getSelectionModel().getSelectedItem()));
		OtherBill  otherBill = otherBillBean.getObject();
		if(isValidate(otherBill)){
			if (date.getSelectedDate()!=null) {
				if (date.getSelectedDate().after(new java.util.Date())) {
					dateErrorLabel.setText("Should not be future date");
				}else{
		   otherBill.setStatus(BillStatus.NEW);

		   Date selectedDate = date.getSelectedDate();
		   otherBill.setBillDate(selectedDate);
		   otherBill.setCreatedDate(Utils.getCurrentDate());
		   otherBill.setModifiedDate(Utils.getCurrentDate());
		   otherBill.setVersion(1L);
		 
		   if (otherBill.getId() != null && otherBill.getId().longValue() > 0) {
				   isUpdate = Boolean.TRUE;
				   selectedDate = date.getSelectedDate();
				   otherBill.setBillDate(selectedDate);
				   otherBill.setModifiedDate(Utils.getCurrentDate());
				   //otherBill.setVersion(1L);
				   
				   billService.saveOrUpdateBill(otherBill);
				   System.out.println(">>>>>>. save >>>>>>>"+otherBill.getBillDate()+"Customer Name>>>:"+otherBill.getCustomer());
			}
		   else{
				   otherBill.setStatus(BillStatus.NEW);
				   selectedDate = date.getSelectedDate();
				   otherBill.setBillDate(selectedDate);
				   otherBill.setCreatedDate(Utils.getCurrentDate());
				   otherBill.setModifiedDate(Utils.getCurrentDate());
				   //otherBill.setVersion(1L);
				   
				   billService.saveOrUpdateBill(otherBill);
				   System.out.println(">>>>>>. save >>>>>>>"+otherBill.getBillDate()+"Customer Name>>>:"+otherBill.getCustomer());
				   showBillPopup();
				   onClear();
			}
				}
			if (isUpdate) {
				stateChange.set(Boolean.TRUE);
			}
			}
		}
		}
	
	public void clearErrorLabel(){
		custNameErrorLabel.setText("");
		refnoErrorLabel.setText("");
		dateErrorLabel.setText("");
//		/descriptionErrorLabel.setText("");
		amountErrorLabel.setText("");
	}
	
	private void showBillPopup(){
		
		final FXMLBase<SuccessController> fxmlBase =  ViewHandler.createFXMLBase(Page.SUCCESS_MSG);
		fxmlBase.getController().getStateChange().addListener(new ChangeListener<Boolean>() {
			@Override
			public void changed(ObservableValue<? extends Boolean> arg0,Boolean oldVal, Boolean newVal) {
				if(newVal){
					fxmlBase.getDialogStage().hide();
				}
			}
		});

		ViewHandler.createDialog(fxmlBase, "Bill generated successfully");
		fxmlBase.getDialogStage().showAndWait();
		
	}
	
	public Boolean isValidate(OtherBill otherBill){
		clearErrorLabel();
		Boolean result = Boolean.TRUE;
		if(validator == null){
			validator=Validation.buildDefaultValidatorFactory().getValidator();
		}
		otherBill.setBillDate(date.getSelectedDate());
		
		Set<ConstraintViolation<OtherBill>> constraintViolations = validator.validate(otherBillBean.getObject());
		System.out.println("Error Values>>>>>>>>>>"+otherBill);
		
			
		for (ConstraintViolation<OtherBill> constraintViolation : constraintViolations) {
			
			if (customerName.getSelectionModel().getSelectedItem()==null) {
				System.out.println("Error customername*******"+customerName.getSelectionModel().getSelectedItem());
				custNameErrorLabel.setText("Select Customer Name");
			}
			if("referenceNumber".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
				refnoErrorLabel.setText(constraintViolation.getMessage());
				result=Boolean.FALSE;
			}
			if("amount".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
				amountErrorLabel.setText(constraintViolation.getMessage());
				result=Boolean.FALSE;
			}
			if("billDate".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
				dateErrorLabel.setText(constraintViolation.getMessage());
				result=Boolean.FALSE;
			}
			}
			return result;
	   }

	
	  @Override
		public void onClear(){
			System.out.println(">>>>>>. onClear >>>>>>>");
			otherBillBean.clean();
		}
	

	 public void reLoad(OtherBillBean  otherBillBean) {
			this.otherBillBean = otherBillBean;

			init();
			bind();
		}
}
